package com.mathassistant.client.presenter;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.shared.SimpleEventBus;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;
import com.mathassistant.client.event.exercise.ExerciseEditFinishedEvent;
import com.mathassistant.client.helper.RPCCall;
import com.mathassistant.client.service.ExerciseServiceAsync;
import com.mathassistant.client.view.ComponentAnwserView;
import com.mathassistant.shared.ExerciseDTO;
import com.mathassistant.shared.TopicDTO;

public class ExerciseStepEditPresenter implements Presenter{

	public interface Display{
		HasClickHandlers getAddButton();
		
		HasClickHandlers getSubtractButton();
		
		HasClickHandlers getSaveButton();
		
		HasClickHandlers getCloseButton();
		
		HasClickHandlers getAddImage();
		
		HasClickHandlers getSubtractImage();
		
		void setAddComponent(ComponentAnwserPresenter component);
		
		void setSubtractComponent(ComponentAnwserPresenter component);
		
		Widget asWidget();
	}

	private List<ComponentAnwserPresenter> listComponent = 
		new ArrayList<ComponentAnwserPresenter>();
	private TopicDTO topic;
	private ExerciseDTO exercise;
	private int indexBeginList = 0;
	private final SimpleEventBus eventBus;
	private final ExerciseServiceAsync rpcService;
	private Display display;
	
	public ExerciseStepEditPresenter(ExerciseDTO exercise, TopicDTO topic, 
			int indexBeginList, ExerciseServiceAsync rpcService, 
			SimpleEventBus eventBus, Display view){
		
		this.exercise = exercise;
		this.topic = topic;
		this.indexBeginList = indexBeginList;
		this.rpcService = rpcService;
		this.eventBus = eventBus;
		this.display = view;
		
		initFillData();
		bind();
	}
	
	private void bind() {
		// TODO Auto-generated method stub
		display.getAddButton().addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				// TODO Auto-generated method stub
				int i = listComponent.size();
				ComponentAnwserPresenter anwser = new ComponentAnwserPresenter(i, "bước giải thứ "+ i, "nội dung bước giải thứ " + i, eventBus, new ComponentAnwserView());
				listComponent.add(anwser);
				display.setAddComponent(anwser);
			}
		});
		display.getSubtractButton().addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				// TODO Auto-generated method stub
				if(listComponent.size() > 2){
					display.setSubtractComponent(listComponent.get(listComponent.size()-1));
					listComponent.remove(listComponent.size()-1);
				} else {
					Window.alert("Giới hạn : bài tập phải có ít nhất một bước giải!");
				}
			}
		});
		display.getSaveButton().addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				// TODO Auto-generated method stub
				doSave();
			}
		});
		display.getCloseButton().addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				// TODO Auto-generated method stub
				doClose();
			}
		});
		
	}

	protected void doSave() {
		// TODO Auto-generated method stub
		if(exercise == null){
			getExerciseFromDisplay();
			addNewExercise();
		}
		else
		{
			getExerciseFromDisplay();
			updateExercise();
		}
	}

	private void addNewExercise() {
		// TODO Auto-generated method stub
		new RPCCall<Void>() {

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				Window.alert("Save exercise error caught: " + caught.getMessage());
			}

			@Override
			public void onSuccess(Void result) {
				// TODO Auto-generated method stub
				Window.alert("Success adding new exercise.");
				doClose();
			}

			@Override
			protected void callService(AsyncCallback<Void> cb) {
				// TODO Auto-generated method stub
				rpcService.createExercise(exercise, topic, cb);
			}
		}.retry(3);
	}
	private void updateExercise() {
		// TODO Auto-generated method stub
		new RPCCall<Void>() {

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				Window.alert("Save exercise error caught: " + caught.getMessage());
			}

			@Override
			public void onSuccess(Void result) {
				// TODO Auto-generated method stub
				Window.alert("Success Updating exercise.");
				doClose();
			}

			@Override
			protected void callService(AsyncCallback<Void> cb) {
				// TODO Auto-generated method stub
				rpcService.updateExercise(exercise, cb);
			}
		}.retry(3);
	}
	protected void doClose() {
		// TODO Auto-generated method stub
		eventBus.fireEvent(new ExerciseEditFinishedEvent(exercise, topic, indexBeginList));
	}
	
	private void getExerciseFromDisplay() {
		// TODO Auto-generated method stub
		if(exercise == null)
			exercise = new ExerciseDTO();
		exercise.setQuestion(listComponent.get(0).getDisplay().getContentHTML().getHTML());
		exercise.getChooses().clear();
		for(int i = 0; i < listComponent.size()-1; i++){
			exercise.getChooses().add(listComponent.get(i+1).getDisplay().getContentHTML().getHTML());
		}
		
	}

	private void initFillData() {
		// TODO Auto-generated method stub
		if(exercise != null){
			//add component question
			ComponentAnwserPresenter question = new ComponentAnwserPresenter(0, "câu hỏi", exercise.getQuestion(), eventBus, new ComponentAnwserView());
			listComponent.add(question);
			display.setAddComponent(question);
			for(int i = 0 ; i < exercise.getChooses().size(); i++){
				ComponentAnwserPresenter anwser = new ComponentAnwserPresenter(i+1, "bước giải thứ " + String.valueOf(i + 1), exercise.getChooses().get(i), eventBus, new ComponentAnwserView());
				listComponent.add(anwser);
				display.setAddComponent(anwser);
			}
		} else {
			ComponentAnwserPresenter question = new ComponentAnwserPresenter(0, "câu hỏi", "nội dung câu hỏi ???", eventBus, new ComponentAnwserView());
			listComponent.add(question);
			display.setAddComponent(question);
			ComponentAnwserPresenter anwser = new ComponentAnwserPresenter(1, "bước giải thứ 1", "nội dung bước giải thứ 1", eventBus, new ComponentAnwserView());
			listComponent.add(anwser);
			display.setAddComponent(anwser);
		}
	}

	@Override
	public void go(HasWidgets container) {
		// TODO Auto-generated method stub
		container.clear();
		container.add(display.asWidget());
	}

	@Override
	public void go() {
		// TODO Auto-generated method stub
		
	}

	public TopicDTO getTopic() {
		return topic;
	}

	public void setTopic(TopicDTO topic) {
		this.topic = topic;
	}

	public ExerciseDTO getExercise() {
		return exercise;
	}

	public void setExercise(ExerciseDTO exercise) {
		this.exercise = exercise;
	}

	public int getIndexBeginList() {
		return indexBeginList;
	}

	public void setIndexBeginList(int indexBeginList) {
		this.indexBeginList = indexBeginList;
	}

	public Display getDisplay() {
		return display;
	}

	public void setDisplay(Display display) {
		this.display = display;
	}

	public SimpleEventBus getEventBus() {
		return eventBus;
	}

	public ExerciseServiceAsync getRpcService() {
		return rpcService;
	}

	public void setListComponent(List<ComponentAnwserPresenter> listComponent) {
		this.listComponent = listComponent;
	}

	public List<ComponentAnwserPresenter> getListComponent() {
		return listComponent;
	}
	
}
